package com.justreading.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * @author LYJ
 * @Description 群聊系统的服务端
 * @date 2021 年 10 月 07 日 16:53
 */
public class GroupChatServer {
    public static void main(String[] args) {
        GroupChatServer groupChatServer = new GroupChatServer();
        groupChatServer.listen();
    }

    private ServerSocketChannel serverSocketChannel;
    private final  static  int PORT = 6667;
    private final  static  InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1",PORT);
    private Selector selector;

    //完成初始化
    public GroupChatServer(){
        try {
            serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.socket().bind(inetSocketAddress);
            serverSocketChannel.configureBlocking(false);
            selector = Selector.open();
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //开始监听
    public void listen(){
        while (true){
            try {
                if(selector.select(1000) == 0){
                    continue;
                }
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()){
                    SelectionKey key = iterator.next();
                    if(key.isAcceptable()){
                        SocketChannel socketChannel = serverSocketChannel.accept();
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector,SelectionKey.OP_READ);
                        System.out.println(socketChannel.getRemoteAddress() + "已上线");
                    }
                    if(key.isReadable()){
                        readData(key);
                    }
                    iterator.remove();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //接受客户端传送来的消息
    private  void readData(SelectionKey key){
        SocketChannel  channel = (SocketChannel)key.channel();
        try {
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            int read = channel.read(byteBuffer);
            if(read > 0){
                String msg = new String(byteBuffer.array());
                System.out.println("收到" + channel.getRemoteAddress() + "发送的" + msg);
                sendToAnther(channel,msg);
            }
        } catch (IOException e) {
            try {
                System.out.println(channel.getRemoteAddress() + "离线");
                key.cancel();
                channel.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    private void sendToAnther(SocketChannel self,String msg){
        for(SelectionKey key : selector.keys()){
            Channel targetChannel = key.channel();
            if(targetChannel instanceof SocketChannel && targetChannel != self) {
                SocketChannel socketChannel = (SocketChannel) targetChannel;
                ByteBuffer byteBuffer = ByteBuffer.wrap(msg.getBytes());
                try {
                    socketChannel.write(byteBuffer);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
